package com.myplans.client;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.InlineHyperlink;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.myplans.client.controller.HomeController;
import com.myplans.client.event.AddPlanEvent;
import com.myplans.client.event.SearchEvent;
import com.myplans.client.event.SignInUserEvent;
import com.myplans.client.event.SignUpUserEvent;
import com.myplans.client.service.PlanService;
import com.myplans.client.service.PlanServiceAsync;
import com.myplans.client.service.UserService;
import com.myplans.client.service.UserServiceAsync;
import com.myplans.client.view.custom.AddPlanDialogBox;
import com.myplans.shared.Category;
import com.myplans.shared.FacebookUtil;
import com.myplans.shared.Plan;
import com.myplans.shared.User;

public class AppController implements Presenter, ValueChangeHandler<String> {
	
	public interface Display {

		public Widget asWidget();
		
		public TextBox getSignInEmail();

		public PasswordTextBox getSignInPasword();

		public Button getSignInButton();
		
		public TextBox getSignUpEmail();
		
		public TextBox getSignUpName();

		public PasswordTextBox getSignUpPasword();

		public Button getSignUpButton();
		
		public FlowPanel getCentralPanel();
		
		public AddPlanDialogBox getAddPlanDialogBox();
		
		public InlineHyperlink getSignIn();

		public InlineHyperlink getSignUp();
		
		public void replaceLinks(boolean replace);

		public InlineHyperlink getLogout();

		public void hideDialogBoxes();
		
		public TextBox getSearchTextBox();

	}

	private Display display;
	private HandlerManager eventBus = new HandlerManager(null);
	private Map<String, Category> categories = new HashMap<String, Category>();

	private HasWidgets container;
	
	UserServiceAsync userServiceAsync = (UserServiceAsync) GWT.create(UserService.class);
	PlanServiceAsync planServiceAsync = (PlanServiceAsync) GWT.create(PlanService.class);
	HomeController homeController = new HomeController(eventBus, userServiceAsync, planServiceAsync);

	public AppController() {
		History.addValueChangeHandler(this);
	}

	public void go(HasWidgets container) {
		
		this.display = (Display) container;
		bind();
		homeController.go(container);
		
		planServiceAsync.getCategories(new AsyncCallback<List<Category>>() {
			
			@Override
			public void onSuccess(List<Category> result) {
				for (Category categ : result) {
					categories.put(categ.getName(), categ);
					display.getAddPlanDialogBox().getCategory().addItem(categ.getName());
				}
			}
			
			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}
		});

		if (History.getToken().equals("")) {
			History.newItem(HistoryTokens.HOME.getId());
		} else {
			History.fireCurrentHistoryState();
		}
	}

	private void bind() {
		display.getSearchTextBox().addKeyPressHandler(new KeyPressHandler() {

			@Override
			public void onKeyPress(KeyPressEvent event) {
				// TODO Auto-generated method stub
				TextBox sender = (TextBox) event.getSource();

				if (sender.isReadOnly() || !sender.isEnabled()) {
					return;
				}

				Character charCode = event.getCharCode();

				// allow digits, '.' and non-characters
				if (charCode == KeyCodes.KEY_ENTER) {
					if ("".equals(sender.getText()) || sender.getText() == null) {
						return;
					} else {
						eventBus.fireEvent(new SearchEvent(sender.getText()));
					}
				}
			}
		});
		display.getSignInButton().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent arg0) {
				eventBus.fireEvent(new SignInUserEvent(display.getSignInEmail().getText(), 
						display.getSignInPasword().getText()));
				display.hideDialogBoxes();
			}
		});
		display.getSignUpButton().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent arg0) {
				User user = new User();
				user.setName(display.getSignUpName().getText());
				user.setEmail(display.getSignUpEmail().getText());
				user.setPassword(display.getSignUpPasword().getText());
				eventBus.fireEvent(new SignUpUserEvent(user));
				display.hideDialogBoxes();
			}
		});
		display.getAddPlanDialogBox().getAddPlanButton().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				Plan plan = new Plan();
				AddPlanDialogBox dialogBox = display.getAddPlanDialogBox();
				plan.setName(dialogBox.getName().getText());
				plan.setDate(dialogBox.getDate());
				plan.setLocation(dialogBox.getLocation().getText());
				plan.setDescription(dialogBox.getDescription().getText());
				plan.setUser(UserUtil.user);
				plan.setCategory(categories.get(dialogBox.getCategory()
						.getValue(dialogBox.getCategory().getSelectedIndex())));
				eventBus.fireEvent(new AddPlanEvent(plan));
				if (dialogBox.getShareOnFacebook().getValue() == true) {
					try {
						new RequestBuilder(RequestBuilder.POST,
							FacebookUtil.getPublishFeedUrl(UserUtil.access_token, plan))
								.sendRequest("", new RequestCallback() {

									@Override
									public void onResponseReceived(
											Request arg0, Response arg1) {
//										Window.alert("A mers!!!");
									}

									@Override
									public void onError(Request arg0,
											Throwable e) {
//										Window.alert(e.getMessage());
									}
								});
					} catch (RequestException e) {
//						Window.alert(e.getMessage());
					}
				}
				display.hideDialogBoxes();
			}
		});
	}
	
	public void onValueChange(ValueChangeEvent<String> event) {
	}
}
